﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Navigation;
using Hammock;
using Hammock.Web;
using Microsoft.Phone.Controls;
using Hammock.Authentication.OAuth;
using MyMeetup.Controls;
using Newtonsoft.Json;



namespace MyMeetup
{
    public partial class LoginPage : PhoneApplicationPage
    {
        AppSettings settings = new AppSettings();
        const string Key = "qhjilk0g8ppffjq2f2eu52vc0s";
        const string Secret = "p2677dcel6r3thhmshs13ebp37";
        private Popup _popup;
        private PopupProgress _progress;
        
        public LoginPage()
        {
            InitializeComponent();
            this.Loaded += PageLoaded;
            var request = new MeetupOAuthRequest("request");

            // post request for access token
            request.Client.BeginRequest(request, new RestCallback(FetchAccessTokenCallback));

        }


        private void PageLoaded(object sender, RoutedEventArgs e)
        {
            ClearBackStack();
        }

        private void ClearBackStack()
        {
            while(NavigationService.CanGoBack)
            {
                NavigationService.RemoveBackEntry();
            }
        }

        private void ShowProgressPopup()
        {
            _popup = new Popup();
            _progress = new PopupProgress();
            _popup.Child = _progress;
            _progress.performanceProgressBar1.IsIndeterminate = true;
            _popup.IsOpen = true;
        }


        private void HideProgressPopup()
        {
            Dispatcher.BeginInvoke(() =>
            {
                _progress.performanceProgressBar1.IsIndeterminate = false;
                    _popup.IsOpen = false;
            });
        }

        private void UpdatePopup(string status)
        {
            Dispatcher.BeginInvoke(() =>
                                   _progress.StatusItem = status
                );
        }


        /// <summary>
        /// Gets the oauth token & secret from the initial oauth request, displays logon to user
        /// </summary>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <param name="userstate"></param>
        private void FetchAccessTokenCallback(RestRequest request, RestResponse response, object userstate)
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                const string authUrl = "http://www.meetup.com/authorize/?oauth_token=";

                settings.OAuthToken = ResponseHelper.GetQueryParameter(response.Content, "oauth_token");
                settings.TokenSecret = ResponseHelper.GetQueryParameter(response.Content, "oauth_token_secret");

                // display logon page using oauth token
                Dispatcher.BeginInvoke(() =>
                                           {
                                               browser.Visibility = Visibility.Visible;
                                               browser.Navigate(new Uri(authUrl + settings.OAuthToken));
                                           }
                    );
            }
            else
            {
                Dispatcher.BeginInvoke(() => MessageBox.Show("Could not connect to Meetup.com"));
            }
        }


        /// <summary>
        /// watches each time the browser page is loaded. Once user logs in and authorizes app, oauth verifier token is returned
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BrowserPageLoaded(object sender, NavigationEventArgs e)
        {

            if (!e.Uri.Query.Contains("oauth_verifier")) return;

            string oauthVerifier = ResponseHelper.GetQueryParameter(e.Uri.Query.TrimStart('?'), "oauth_verifier");
            if (oauthVerifier != string.Empty)
            {
                settings.OAuthVerifier = oauthVerifier;

                Dispatcher.BeginInvoke(() =>
                                           {
                                               browser.Visibility = Visibility.Collapsed;
                                           });
                ShowProgressPopup();
                Verify();
            }

        }

        private void Verify()
        {
            const string authUrl = "https://api.meetup.com/oauth/access/";

            // Use Hammock to set up our authentication credentials
            var credentials = new OAuthCredentials()
            {
                Type = OAuthType.AccessToken,
                SignatureMethod = OAuthSignatureMethod.HmacSha1,
                ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
                Token = settings.OAuthToken,
                TokenSecret = settings.TokenSecret,
                ConsumerKey = Key,
                ConsumerSecret = Secret,
                Verifier = settings.OAuthVerifier
            };

            // Use Hammock to create a rest client
            var client = new Hammock.RestClient()
            {
                Authority = authUrl,
                Credentials = credentials
            };

            // Use Hammock to create a request
            var request = new RestRequest();
            
            // Get the response from the request
            UpdatePopup("Verifying access...");
 
            client.BeginRequest(request, new RestCallback(VerifyCallback));
            
        }

        private void VerifyCallback(RestRequest request, RestResponse response, object userstate)
        {
            UpdatePopup("Verification complete.");
            settings.OAuthToken = ResponseHelper.GetQueryParameter(response.Content, "oauth_token");
            settings.TokenSecret = ResponseHelper.GetQueryParameter(response.Content, "oauth_token_secret");
            settings.IsAuthenticated = true;

            LoadUserDetails();

        }


        private void LoadUserDetails()
        {
            UpdatePopup("Loading user...");
            
            var ds = new DataService();
            ds.GetMember(UserLoaded, ResponseHelper.ErrorCallback);

        }

        private void UserLoaded(Member member)
        {
            UpdatePopup("User loaded.");
            App.Settings.AuthUser = member;
            HideProgressPopup();
            Dispatcher.BeginInvoke(() =>
                                   NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative))

                );

        }
    }
}